﻿#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
#include<iostream>

using namespace std;

namespace dw
{
	class string
	{
	public:
		/* 迭代器 */
		typedef char* iterator;                               // 定义非const版本的迭代器类型
		typedef const char* const_iterator;                   // 定义const版本的迭代器类型

		iterator begin() { return _str; }                     // 返回非const版本的指向第一个有效元素的迭代器
		iterator end()   { return _str + _size; }             // 返回非const版本的指向最后一个有效元素的后一个位置的迭代器

		const_iterator begin() const { return _str; }         // 返回const版本的指向第一个有效元素的迭代器
		const_iterator end()   const { return _str + _size; } // 返回const版本的指向最后一个有效元素的后一个位置的迭代器

		/*四个特殊的成员函数*/
		string(const char* str = "");  // 默认构造函数
		string(const string& s);       // 拷贝构造函数
		string& operator=(string s);   // 赋值运算符重载函数
		~string();                     // 析构函数

		/* 增 */
		void insert(size_t pos, char ch);          // 在指定位置插入一个字符
		void insert(size_t pos, const char* str);  // 在指定位置插入一个C风格的字符串
		void push_back(char ch);                   // 尾插
		void append(const char* str);              // 追加字符串
		string& operator+=(char ch);               // += 一个字符
		string& operator+=(const char* str);       // += 一个C风格的字符串

		/* 删 */
		void erase(size_t pos, size_t len = npos); // 从指定位置删除指定长度的字符串
		void clear();							   // 清空字符串

		/* 查 */
		size_t find(char ch, size_t pos = 0);         // 从指定位置查找指定字符（默认从0下标开始找）
		size_t find(const char* str, size_t pos = 0); // 从指定位置查找指定字符串（默认从0下标开始找）
		
		/* 改 */
		const char& operator[](size_t pos) const; // 重载const版本的[]
		char& operator[](size_t pos);             // 重载非const版本的[]

		/* 容量相关操作 */
		bool empty()        const { return 0 == _size; }   // 判断是否为空
		size_t size()       const { return _size; }        // 返回有效元素的个数
		size_t capacity()   const { return _capacity; }    // 返回容量大小
		void resize(size_t newSize, char c = '\0');        // 改变 _size   
		void reserve(size_t n);                            // 改变 _capacity（不缩容）

		/* 其他操作 */

		void swap(string& s);                              // 交换两个字符串

		string substr(size_t pos = 0, size_t len = npos);  // 从指定位置提取指定长度的子串

		const char* c_str() const { return _str; }         // 返回C风格的字符串

	private:
		size_t _capacity = 0;  // 记录容量大小
		size_t _size = 0;	   // 记录有效元素的个数
		char* _str = nullptr;  // 指向当前字符串

		const static size_t npos = -1; // 无符号整数类型的-1表示成2进制为32位全1，是一个非常大的整数
	};

	istream& operator>>(istream& in, string& s);         // 重载流提取
	ostream& operator<<(ostream& out, const string& s);	 // 重载流插入
}